package com.baohulu.baohulu.activity;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.LogoPosition;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;
import com.baohulu.baohulu.R;
import com.baohulu.baohulu.activity.account.AccountActivity;
import com.baohulu.baohulu.activity.userprofile.UserProfileActivity;
import com.baohulu.baohulu.base.BaseResponseCallback;
import com.baohulu.baohulu.bean.Device;
import com.baohulu.baohulu.common.Const;
import com.baohulu.baohulu.utils.HttpUtil;
import com.baohulu.baohulu.utils.JsonUtil;
import com.baohulu.baohulu.utils.SharedPrefUtil;
import com.baohulu.baohulu.utils.ToastUtil;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import pub.devrel.easypermissions.EasyPermissions;

/**
 * 主界面
 */
public class MainActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks,
        SensorEventListener, BaiduMap.OnMapLoadedCallback, BaiduMap.OnMapTouchListener {

    private static final int REQUEST_PERMISSIONS = 12;
    private static final String TAG = "MainActivity";

    @BindView(R.id.map_view)
    MapView mapView;
    @BindView(R.id.drawer)
    DrawerLayout dlUserCenter;
    @BindView(R.id.tv_user_name)
    TextView tvUserNickname;

    private BaiduMap mBaiduMap;
    private LocationClient mLocationClient;

    private SensorManager mSensorManager;
    private Sensor mOrientationSensor;
    private double lastLatitude;
    private double lastLongitude;
    private float direction;
    private boolean isRequestLocate = true;
    private boolean isTouch = false;

    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        if (isUserLogin()) {
            checkUserRentState();
        }
        iniView();
        initLocationClient();
        initSensor();
    }

    /**
     * 检查用户是否登录
     */
    private boolean isUserLogin() {
        return SharedPrefUtil.getBoolean(Const.SpKey.IS_LOGIN);
    }

    /**
     * 检查用户租借状态，如果用户处在租借状态，跳转到计时页面
     */
    private void checkUserRentState() {
        String url = getString(R.string.url_base) + getString(R.string.url_check_user_rent_state);
        HttpUtil.post(this, url, new JSONObject(), new BaseResponseCallback() {
            @Override
            public void onStart() {

            }

            @Override
            public void onJsonObjectResponse(JSONObject jsonObject) {
                super.onJsonObjectResponse(jsonObject);
                try {
                    int state = jsonObject.getInt("state");
                    if (state == 1) {//用户正在租借
                        long startTime = jsonObject.getLong("start_time");
                        String ballKey = jsonObject.getString("ball_key");
                        String eqKey = jsonObject.getString("eq_key");
                        int doorId = jsonObject.getInt("door_id");
                        double ballPrice = jsonObject.getDouble("ball_price");
                        //跳转到计时页面
                        goToTimerActivity(startTime, ballKey, eqKey, ballPrice, doorId);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(String msg) {
                Log.e(TAG, "onFailure: " + msg);
            }
        });
    }

    /**
     * 跳转到计时页面
     */
    private void goToTimerActivity(long startTime, String ballKey, String eqKey, double ballPrice, int doorId) {
        Intent intent = new Intent(this, TimerActivity.class);
        intent.putExtra(Const.Extra.START_TIME, startTime)
                .putExtra(Const.Extra.BALL_PRICE, ballPrice)
                .putExtra(Const.Extra.EQ_KEY, eqKey)
                .putExtra(Const.Extra.BALL_KEY, ballKey)
                .putExtra(Const.Extra.DOOR_INDEX, doorId);
        startActivity(intent);
    }

    private void iniView() {
        initNickname();
        initMapView();
    }

    private void initNickname() {
        //初始化昵称
        String nickname = SharedPrefUtil.getString(Const.SpKey.LOGIN_USER_NICKNAME);
        if (TextUtils.isEmpty(nickname)) {
            nickname = "用户未登录";
        }
        tvUserNickname.setText(nickname);
    }

    private void initMapView() {
        mapView.showZoomControls(false);//隐藏地图放大缩放按钮
        mapView.showScaleControl(false);//隐藏比例尺
        mapView.setLogoPosition(LogoPosition.logoPostionCenterBottom);
        mBaiduMap = mapView.getMap();
        MyLocationConfiguration configuration = new MyLocationConfiguration(MyLocationConfiguration.LocationMode.FOLLOWING, true, null);
        mBaiduMap.setMyLocationConfiguration(configuration);
        mBaiduMap.getUiSettings().setRotateGesturesEnabled(false);//禁止旋转地图
        mBaiduMap.setMyLocationEnabled(true);
        mBaiduMap.setOnMapLoadedCallback(this);
        mBaiduMap.setOnMapTouchListener(this);
    }

    private void initLocationClient() {
        mLocationClient = new LocationClient(getApplicationContext());
        mLocationClient.registerLocationListener(new MyLocationListener());
        configLocationOption();
    }

    /**
     * 配置定位参数
     */
    private void configLocationOption() {
        LocationClientOption option = new LocationClientOption();
        //可选，设置定位模式，默认高精度
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        option.setCoorType("bd09ll");
        //可选，设置发起定位请求的间隔，int类型，单位ms
        option.setScanSpan(5000);
        //可选，设置是否当GPS有效时按照1S/1次频率输出GPS结果，默认false
        option.setOpenGps(true);
        option.setLocationNotify(false);
        //可选，定位SDK内部是一个service，并放到了独立进程。
        //设置是否在stop的时候杀死这个进程，默认（建议）不杀死，即setIgnoreKillProcess(true)
        option.setIgnoreKillProcess(false);
        //可选，设置是否收集Crash信息，默认收集，即参数为false
        option.SetIgnoreCacheException(false);
        //可选，7.2版本新增能力
        //如果设置了该接口，首次启动定位时，会先判断当前WiFi是否超出有效期，若超出有效期，会先重新扫描WiFi，然后定位
        option.setWifiCacheTimeOut(5 * 60 * 1000);
        //可选，设置是否需要过滤GPS仿真结果，默认需要，即参数为false
        option.setEnableSimulateGps(false);
        //mLocationClient为第二步初始化过的LocationClient对象
        //需将配置好的LocationClientOption对象，通过setLocOption方法传递给LocationClient对象使用
        //更多LocationClientOption的配置，请参照类参考中LocationClientOption类的详细说明
        mLocationClient.setLocOption(option);
    }

    @SuppressWarnings("deprecation")
    private void initSensor() {
        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        if (mSensorManager != null && mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION) != null) {
            mOrientationSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
        }
    }

    @Override
    protected void onStart() {
        super.onStart();
        checkPermissions();
        mLocationClient.start();
    }

    /**
     * 请求所需权限
     */
    private void checkPermissions() {
        String[] permissions = {Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.ACCESS_FINE_LOCATION};
        if (!EasyPermissions.hasPermissions(this, permissions)) {
            EasyPermissions.requestPermissions(this, "应用需要相机和位置权限", REQUEST_PERMISSIONS, permissions);
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        mLocationClient.stop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mSensorManager.unregisterListener(this);
        mapView.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();
        mSensorManager.registerListener(this, mOrientationSensor, SensorManager.SENSOR_DELAY_NORMAL);
    }

    //permission callbacks
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    @OnClick(R.id.location)
    public void locate() {
        isRequestLocate = true;
        isTouch = false;
        mLocationClient.requestLocation();
    }

    /**
     * 打开侧滑菜单
     */
    @OnClick(R.id.user)
    public void openUserCenter() {
        openDrawer();
    }

    private void openDrawer() {
        initNickname();
        dlUserCenter.openDrawer(Gravity.START);
    }

    /**
     * 扫码前判定登录状态
     */
    @OnClick(R.id.scan_qr_code)
    public void beforeScan() {
        //如果已登录，则进行扫码
        if (isUserLogin()) {
            scanQRCode();
        } else {
            //未登录直接跳转到登录界面
            jumpToLogin();
        }
    }

    private void scanQRCode() {
        startActivity(new Intent(this, ScanActivity.class));
    }

    public void jumpToLogin() {
        startActivity(new Intent(this, AccountActivity.class));
    }


    /**
     * 退出登录
     */
    @OnClick(R.id.menu_quit)
    public void logOut() {
        if (isUserLogin()) {
            SharedPrefUtil.clearLoginState();
            ToastUtil.showToast(R.string.menu_logout);
            closeDrawer();
        }
    }

    private void closeDrawer() {
        dlUserCenter.closeDrawer(Gravity.START);
    }

    @OnClick(R.id.user_info)
    public void userInfoClick() {
        editUserProfile();
    }

    private void editUserProfile() {
        if (isUserLogin()) {
            Intent intent = new Intent(this, UserProfileActivity.class);
            startActivity(intent);
        } else {
            jumpToLogin();
        }
        closeDrawer();
    }

    /**
     * 关于我们
     */
    @OnClick(R.id.menu_about_us)
    public void aboutUs() {
        closeDrawer();
        startActivity(new Intent(this, AboutUsActivity.class));
    }

    @OnClick(R.id.menu_edit_profile)
    public void editProfileClick() {
        editUserProfile();
    }

    @OnClick(R.id.menu_my_record)
    public void myRecord() {
        Intent intent = new Intent(this, RecordActivity.class);
        startActivity(intent);
        closeDrawer();
    }

    @OnClick(R.id.menu_my_score)
    public void myScore() {
    }

    @OnClick(R.id.menu_my_wallet)
    public void myWallet() {
//        Intent intent = new Intent(this, MyWalletActivity.class);
//        startActivity(intent);
//        closeDrawer();
    }

    @Override
    public void onPermissionsGranted(int requestCode, List<String> perms) {
        if (requestCode == REQUEST_PERMISSIONS) {
            Log.d(TAG, "onPermissionsGranted: 权限已授予");
        }
    }

    @Override
    public void onPermissionsDenied(int requestCode, List<String> perms) {
        if (requestCode == REQUEST_PERMISSIONS) {
            Toast.makeText(this, "权限被拒绝", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        //更新位置指针方向
        direction = event.values[0];
        updateLocationOnMap(lastLatitude, lastLongitude, direction);
    }

    private void updateLocationOnMap(double latitude, double longitude, float direction) {
        if (!isTouch) {//用户在移动地图后不再实时更新位置
            // 构造定位数据
            MyLocationData locData = new MyLocationData.Builder()
                    .direction(direction)
                    .latitude(latitude)
                    .longitude(longitude)
                    .build();
            mBaiduMap.setMyLocationData(locData);
        }

    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

    /**
     * 地图加载成功后回调
     */
    @Override
    public void onMapLoaded() {
        //获取附近球柜
        getSurroundDevices(lastLatitude, lastLongitude);
    }

    /**
     * 获取附近的球柜
     *
     * @param latitude  纬度
     * @param longitude 经度
     */
    private void getSurroundDevices(double latitude, double longitude) {
        final JSONObject data = new JsonUtil.JsonBuilder()
                .put("latitude", latitude)
                .put("longitude", longitude)
                .build();
        String url = getString(R.string.url_base) + getString(R.string.url_get_surround_device);
        HttpUtil.post(this, url, data, new BaseResponseCallback() {
            @Override
            public void onStart() {

            }

            @Override
            public void onJsonObjectResponse(JSONObject jsonObject) {
                super.onJsonObjectResponse(jsonObject);
                try {
                    int state = jsonObject.getInt("state");
                    if (state == 1) {
                        JSONArray devices = jsonObject.getJSONArray("devices");
                        List<Device> deviceList = new ArrayList<>();
                        for (int i = 0; i < devices.length(); i++) {
                            JSONObject deviceObject = devices.getJSONObject(i);
                            Device device = Device.fromJsonObject(deviceObject);
                            deviceList.add(device);
                        }
                        addDeviceMarkers(deviceList);
                    } else {
                        Log.e(TAG, "onJsonObjectResponse: 获取附近设备出错 state=0");
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(String msg) {
                Log.e(TAG, "onFailure: " + msg);
            }
        });
    }

    /**
     * 添加附近设备标记
     */
    public void addDeviceMarkers(List<Device> deviceList) {
        List<OverlayOptions> optionList = new ArrayList<>();
        for (Device device : deviceList) {
            //设置坐标点
            LatLng point = new LatLng(device.getLatitude(), device.getLongitude());
            //创建OverlayOptions属性
            BitmapDescriptor marker = BitmapDescriptorFactory.fromResource(R.drawable.ic_marker);
            OverlayOptions options = new MarkerOptions().position(point).icon(marker);
            optionList.add(options);
        }
        //在地图上批量添加标记
        mBaiduMap.addOverlays(optionList);
    }

    @Override
    public void onTouch(MotionEvent motionEvent) {
        isTouch = true;
    }

    class MyLocationListener extends BDAbstractLocationListener {

        @Override
        public void onReceiveLocation(BDLocation location) {
            lastLatitude = location.getLatitude();
            lastLongitude = location.getLongitude();
//            Log.d(TAG, "onReceiveLocation: 纬度：" + lastLatitude + ",经度：" + lastLatitude);
            updateLocationOnMap(lastLatitude, lastLongitude, direction);
            if (isRequestLocate) {//用户重新定位后获取附近柜子
                getSurroundDevices(lastLatitude, lastLongitude);
                isRequestLocate = false;
            }
        }
    }

}
